//including interfcae and testcase files

`timescale 1ns/1ns
import uvm_pkg::* ;
`include "uvm_macros.svh"

`include "axi_lite_master.v"
`include "issiflashwrapper.v"
`include "axi_lite_interface.sv"
`include "axi_lite_base_test.sv"
`include "IOBUF.v"
`include "glbl.v"

`include "AutoBootReg.sv"   // not working
`include "BLK64_ERSUS_B0_REL_30.sv"   
`include "BLK64_ERSUS_75_REL_7A.sv"   
`include "BLK32_ERSUS_75_REL_7A.sv"   
`include "BLK32_ERSUS_B0_REL_30.sv"   
`include "QBLK32_ERSUS_B0_REL_30.sv"    // not working
`include "RDJDID.sv"
`include "RDJDIDQ.sv"
`include "RDMDID.sv"
`include "PP_12_4BYTS.sv"  // need to add some code 
`include "PP_NORD.sv"
`include "PP_FRD.sv"
`include "PP_FRDTR.sv"
`include "PP_FRDTR_3BYTE.sv"  // not working need to add extebded bit unable to add extended bit
`include "PP_FRQIO.sv"        // working fine but QE bit is not enabled
`include "PP_FRDIO.sv"
`include "PP_FRDDTR.sv"
`include "PP_4FRDTR.sv"
`include "PP_4FRQDTR.sv"
`include "FastReadDTR_3bytes.sv"
`include "FastReadDualIODTR_3bytes.sv"
`include "PPB_4byte_EraseProtected_Quad.sv"  // not working 
`include "PPB_4byte_WriteProtected_Quad.sv"  // not working 
`include "writeReadStatusRegister.sv"
`include "BlockEraseSuspendResume.sv"
`include "BlockEraseSuspendResume_1.sv"
`include "ChipErasePageProgram_60.sv"
`include "ChipErasePageProgram_60_Qpi.sv"
`include "ChipErasePageProgramRead_60.sv"
`include "ChipErasePageProgramRead_C7.sv"
`include "DYB3bytesWriteRead.sv"   // not working
`include "dyb4bytesWriteRead.sv"   // not working
`include "DeepPowerDownMode.sv"      
`include "Gangblock.sv"   
`include "Gangblock_7E.sv"   
`include "Gangblock_7E_Unblock_98.sv"   
`include "Freeze_InformationRow.sv"   // Quad mode
`include "Freeze_InformationRow_spi.sv"   // spi mode
`include "SIOO_PageProgram_Read.sv"   
`include "SIOO_PP_Read.sv"   // write is not working for SIOO
`include "InformationRowProgrmamWriteRead.sv" // not working as per spec
//`include "BlockErase64KB_SuspendResume_Quad.sv" 
`include "BlockErase64KB_75_Suspend_7A_Resume_Quad.sv" 
`include "BlockErase64KB_B0_Suspend_30_Resume_Quad.sv" 
`include "AND_Polling_Mode.sv" 
`include "SE_Polling_Mode.sv" 
`include "OR_Polling_Mode.sv" 
`include "Polling_Mode.sv" 
`include "SectorErase_Suspend_Resume_1.sv" 
`include "SectorErase_Suspend_Resume_Quad.sv" 
`include "SectorErase_Suspend_Resume_1_Quad.sv" 
`include "Page_Program_Suspend_Resume.sv" 
`include "Page_Program_Suspend_Resume_Quad.sv" 
`include "Page_Program_Suspend_Resume_1.sv" 
`include "PPB_3byte_EraseProtected_Quad.sv" 
`include "Page_Program_Suspend_Resume_1_Quad.sv" 
`include "PPB_3byte_WriteProtected_Quad.sv" 
`include "PPBErase_Quad.sv" 
`include "Dyb3bytes_WriteProtected_Quad.sv" 
//`include "DYB3BytesWriteProtectedRead.sv" 
`include "Dyb3bytes_EraseProtected_Quad.sv" 
`include "RDMDID_Quad.sv" 
`include "Read_SFDP_5A_Quad.sv" 
`include "ReadElectricID_Quad.sv" 
`include "SectorErase_Suspend_Resume.sv" 
`include "InformationRowProgrmamRead.sv" 
`include "InformationRowWriteEraseRead_Quad.sv" 
`include "InformationRowRead_Quad.sv" 
`include "InformationRowWriteRead_Quad.sv" 
`include "DeepPowerDownMode_Quad.sv" 
//---------------------------------------------------------------

module axi_master_tb_top_qspi;

  //---------------------------------------
  //clock and reset signal declaration
  //---------------------------------------
  bit aclk_i;
  bit areset_n_i;
  
  //---------------------------------------
  //clock generation
  //---------------------------------------
  always #5000 aclk_i = ~aclk_i;
  
  //---------------------------------------
  //reset Generation
  //---------------------------------------
/*   initial begin
    areset_n_i = 1;
	#50 areset_n_i =0;   
	#50 areset_n_i =1;
	end */
	
   initial begin
    areset_n_i = 1;
    #15000 areset_n_i =0;
		#45000 areset_n_i =1; //45 ns
   end

  //---------------------------------------
  //interface instance
  //---------------------------------------
  axi_lite_interface intf(aclk_i,areset_n_i);
  
  //---------------------------------------
  //axi-master instance
  //---------------------------------------
  
  // Write Address Channel Signals
  wire [31:0] m_axi_awaddr;
  wire m_axi_awvalid;
  wire m_axi_awready;
  wire [3:0] m_axi_awprot;
  // Write Data Channel Signals
  wire [31:0] m_axi_wdata;
  wire [3:0] m_axi_wstrb;
  wire m_axi_wvalid;
  wire m_axi_wready; 
  // Write Response Channel Signals
  wire [1:0] m_axi_bresp;
  wire m_axi_bvalid;
  wire m_axi_bready;  
  // Read Address Channel Signals
  
  wire [31:0] m_axi_araddr;
  wire m_axi_arvalid;
  wire m_axi_arready;
  
  // Read Data Channel Signals
  wire [31:0] m_axi_rdata;
  wire [3:0] m_axi_rresp;
  wire m_axi_rvalid;
  wire m_axi_rready; 
    
  axi_lite_master axi_lite_master_i (
    
    .M_AXI_ACLK       (aclk_i)        ,      
    .M_AXI_ARESETN    (areset_n_i)    ,  
    .M_AXI_AWADDR     (m_axi_awaddr)  ,
    .M_AXI_AWVALID    (m_axi_awvalid) ,
    .M_AXI_AWREADY    (m_axi_awready) ,
    .M_AXI_AWPROT     (m_axi_awprot)  ,
    .M_AXI_WDATA      (m_axi_wdata)   ,
    .M_AXI_WSTRB      (m_axi_wstrb)   ,
    .M_AXI_WVALID     (m_axi_wvalid)  ,   
    .M_AXI_WREADY     (m_axi_wready)  ,   
    .M_AXI_BRESP      (m_axi_bresp)   ,   
    .M_AXI_BVALID     (m_axi_bvalid)  ,          
    .M_AXI_BREADY     (m_axi_bready)  ,  
    .M_AXI_ARADDR     (m_axi_araddr)  ,   
    .M_AXI_ARVALID    (m_axi_arvalid) ,  
    .M_AXI_ARREADY    (m_axi_arready) ,     
    .M_AXI_RDATA      (m_axi_rdata)   ,        
    .M_AXI_RRESP      (m_axi_rresp)   ,
    .M_AXI_RVALID     (m_axi_rvalid)  ,    
    .M_AXI_RREADY     (m_axi_rready)  ,  
    
    //write interface signals
    
    .write_addr_i    (intf.write_addr_i  )  ,
    .write_addrv_i   (intf.write_addrv_i  )  ,  // added signal on 9th jan
    .write_data_i    (intf.write_data_i  )  ,
    .write_datav_i   (intf.write_datav_i )  ,
    .write_strb_i    (intf.write_strb_i  )  ,
    .write_bresp_o   (intf.write_bresp_o )  ,
    .write_bvalid_o  (intf.write_bvalid_o)  ,
	
    //write interface signals
	
    .read_start_i    (intf.read_start_i  )  ,
    .read_addr_i     (intf.read_addr_i   )  ,
    .read_af_i       (intf.read_af_i     )  ,           
    .read_data_o     (intf.read_data_o   )  ,
    .read_datav_o    (intf.read_datav_o) ); 
    
   //---------------------------------------
  //DUT- Qspi slave instance 
  //--------------------------------------
  
  wire        io_mv_clk_o;    
  wire [3:0]  io_mv_io_o  ;   
  wire [3:0]  io_mv_io_enable;
  wire [3:0]  io_ma_io_i_ma_io_i;
  wire        io_mv_ncs_o    ;
  wire [5:0]  interrupts     ;
  wire        RDY_interrupts ;
    
  wire [2:0]  arprot; 
  
  //mkinst_qspi_axi4l mkinst_qspi_axi4l_i
  //mkinst_qspi_axi4l qspi_inst
  mkinst_qspi_axi4l qspi_inst
  
  (.CLK                (aclk_i),      
   .RST_N              (areset_n_i),      
   .AWVALID            (m_axi_awvalid),     
   .AWADDR             (m_axi_awaddr),       
   .AWPROT             (m_axi_awprot),          
   .WVALID             (m_axi_wvalid),        
   .WDATA              (m_axi_wdata),       
   .WSTRB              (m_axi_wstrb),            
   .BREADY             (m_axi_bready),         
   .ARVALID            (m_axi_arvalid),        
   .ARADDR             (m_axi_araddr),        
   .ARPROT             (arprot),       
   .RREADY             (m_axi_rready),     
   .AWREADY            (m_axi_awready),            
   .WREADY             (m_axi_wready),                 
   .BVALID             (m_axi_bvalid),              
   .BRESP              (m_axi_bresp),                   
   .ARREADY            (m_axi_arready),                 
   .RVALID             (m_axi_rvalid),               
   .RRESP              (m_axi_rresp),              
   .RDATA              (m_axi_rdata),           
   .io_mv_clk_o        (io_mv_clk_o),           
   .io_mv_io_o         (io_mv_io_o),          
   .io_mv_io_enable    (io_mv_io_enable),          
   .io_ma_io_i_ma_io_i (io_ma_io_i_ma_io_i),          
   .io_mv_ncs_o        (io_mv_ncs_o),          
   .interrupts         (interrupts),          
   .RDY_interrupts     (RDY_interrupts));
  
//----------------------------------------------------
// logic for controlling the bidirectional in-out signals 		   
//----------------------------------------------------

  glbl glbl_i ();
 
  wire io_0;
  wire io_1;
  wire io_2;
  wire io_3;
	
	IOBUF gpio_iobuf_inst0 (
        .O  (io_ma_io_i_ma_io_i[0]),
        .IO (io_0),
        .I  (io_mv_io_o[0]),
        .T  (~io_mv_io_enable[0]) //high to flash low is from flash
      );
	  
	IOBUF gpio_iobuf_inst1 (
        .O  (io_ma_io_i_ma_io_i[1]),
        .IO (io_1),
        .I  (io_mv_io_o[1]),
        .T  (~io_mv_io_enable[1]) 
      );	

	IOBUF gpio_iobuf_inst2 (
        .O  (io_ma_io_i_ma_io_i[2]),
        .IO (io_2),
        .I  (io_mv_io_o[2]),
        .T  (~io_mv_io_enable[2]) 
      );
	  
	IOBUF gpio_iobuf_inst3 (
        .O  (io_ma_io_i_ma_io_i[3]),
        .IO (io_3),
        .I  (io_mv_io_o[3]),
        .T  (~io_mv_io_enable[3]) 
      );	  

//----------------------------------------------------
// Instantiation of ISSI_Flash_Memory module               
//----------------------------------------------------
	  
issiflashwrapper flash_inst(
        .sclk   (io_mv_clk_o),
        .cs     (io_mv_ncs_o),
        .si     (io_0),
        .so     (io_1),
        .wp     (io_2),
        .sio3   (io_3) 
);   	  
  
  //---------------------------
  //passing the interface handle to lower heirarchy using set method 
  //and enabling the wave dump
  //---------------------------------------
  initial begin 
    uvm_config_db#(virtual axi_lite_interface)::set(uvm_root::get(),"*","vif",intf);
    //$display("interface..intf.read_start_i= %d",intf.read_start_i); 
   // #10000 $finish;
  end
  
  //---------------------------------------
  //calling test
  //---------------------------------------
  initial begin 
    run_test("InformationRowWriteRead_Quad");
     #10000000;
    #10000000;
    /*#10000000;
	 #10000000;
    #10000000;
    #10000000; */
    //$finish;
  end
  
endmodule :axi_master_tb_top_qspi